"""
文件名: Base.py
    是页面自动化测试框架---基础类: 对selenium进行二次封装
    - 打开浏览器
    - 输入网址
    - 浏览器后退/刷新/前进/关闭浏览器
    - 元素定位
    - 元素操作
      - 点击
      - 输入/清空
      - 获取元素属性
      - 获取元素文本
    - 控件操作
公共方法: 在项目中,由专人维护
"""
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys


def open_browser(browser: str = 'chrome'):
    """
    打开浏览器
    :param browser: 浏览器名称
    :return:
    """
    if browser.lower() == 'chrome':
        return webdriver.Chrome()  # 打开谷歌浏览器
    elif browser.lower() == 'firefox':
        return webdriver.Firefox()  # 打开火狐浏览器
    elif browser.lower() == 'edge':
        return webdriver.Edge()  # 打开Edge浏览器
    else:
        print('请选择正确的浏览器,例如: chrome,firefox,edge')
        return None


class Base(object):
    def __init__(self, driver):
        self.driver = driver

    def open_url(self, url: str):
        """
        输入网址
        :param url: 项目地址
        :return:
        """
        try:
            if url.startswith('http://'):  # 判断地址,是否已http://开头
                self.driver.get(url)  # 输入网址
                self.driver.maximize_window()  # 浏览器最大化
            else:
                new_url = 'http://' + url
                self.driver.get(new_url)  # 输入网址
                self.driver.maximize_window()  # 浏览器最大化

        except:
            print('输入的地址不规范')

    def find_element(self, locator: tuple, timeout=10):
        """
        元素定位,定位单个元素,如果元素存在,返回元素本身,反之,返回False
        :param locator: 定位器 ('id','kw')
        :return: WebElement  FALSE
        """
        try:
            return WebDriverWait(self.driver, timeout).until(EC.presence_of_element_located(locator))
        except:
            print(f'元素{locator},不存在')
            return False

    def find_elements(self, locator: tuple, timeout=10):
        """
        元素定位,定位一组元素,如果元素存在,返回元素列表,反之,返回False
        :param locator: 定位器
        :param timeout: 超时时间
        :return:
        """
        try:
            return WebDriverWait(self.driver, timeout).until(EC.presence_of_all_elements_located(locator))
        except:
            print(f'元素{locator},不存在')
            return False

    def click(self, locator: tuple, timeout=10):
        """
        点击
        :param locator: 定位器
        :param timeout: 超时时间
        :return:
        """
        element = self.find_element(locator=locator, timeout=timeout)
        if element is not False:  # 判断元素是否定位成功
            element.click()
        else:
            print('元素不存在,无法执行点击操作')

    def send_keys(self, locator: tuple, text, timeout=10):
        """
        输入
        :param locator: 定位器
        :param text: 输入的内容
        :param timeout: 超时时间
        :return:
        """
        try:
            element = self.find_element(locator=locator, timeout=timeout)
            element.clear()  # 先清空
            element.send_keys(text)  # 再输入
        except:
            print(f'元素{locator}不存在,无法输入')

    def key_event_table(self, locator: tuple, timeout=10):
        """
        键盘事件_table键
        @param locator:
        @param timeout:
        @return:
        """
        element = self.find_element(locator=locator, timeout=timeout)
        if element is not False:
            element.send_keys(Keys.TAB)
        else:
            print('元素不存在,无法执行输入操作')

    def close_browser(self):
        """
        关闭浏览器
        :return:
        """
        self.driver.quit()

    def get_element_text(self, locator: tuple, timeout=10):
        """
        获取元素文本值,如果有,返回文本值内容,如果没有返回False
        @param locator: 定位器
        @param timeout: 超时时间
        @return:
        """
        element = self.find_element(locator=locator, timeout=timeout)
        if element is not False:
            return element.text
        else:
            return False

    def is_text_equal_in_element(self, locator: tuple, text, timeout=10):
        """
        判断已知的文本值是否和元素的文本值相同,如果相同,返回True,反之返回False
        @param locator: 定位器
        @param text: 已知文本值
        @param timeout: 超时时间
        @return:
        """
        result_text = self.get_element_text(locator=locator, timeout=timeout)
        if result_text is not False:
            return result_text == text
        else:
            return result_text

    def get_url(self):
        """
        获取当前窗口url
        @return:
        """
        url = self.driver.current_url
        print(url)
        if url is not False:
            return url
        else:
            return False

    def is_url_equal(self, text):
        """
        判断新窗口url与原窗口url是否相等
        @param text: 新窗口url
        @return:
        """
        new_url = self.get_url()
        if new_url != text:
            return True
        else:
            return False

    def is_selected_submit_radio(self, locator: tuple, timeout=10):
        """
        判断单选框是否被选中
        @return:
        """
        element = self.find_element(locator=locator, timeout=timeout)
        result = element.is_selected()
        if result is not False:
            return result
        else:
            self.click(locator=locator, timeout=timeout)
            return element.is_selected()

    def get_alert_text(self):
        """获取弹窗文本值"""
        return self.driver.switch_to.alert.text

    def Enter_keys(self, locator: tuple, timeout=10):
        """
        键盘事件Enter键
        @param locator:
        @param timeout:
        @return:
        """
        element = self.find_element(locator=locator, timeout=timeout)
        if element is not False:
            element.send_keys(Keys.ENTER)
        else:
            print('元素不存在,无法执行输入操作')

    def into_frame(self, locator: tuple, timeout=10):
        """进入frame"""
        self.driver.switch_to.frame(self.find_element(locator=locator, timeout=timeout))

    def out_frame(self):
        """退出frame"""
        self.driver.switch_to.default_content()

    def up_scroll(self):
        """滚动条向上滚动"""
        self.driver.execute_script('window.scrollTo(0,0)')

    def down_scroll(self):
        """滚动条向下滚动"""
        self.driver.execute_script('window.scrollTo(0,2000)')

    def back_page(self):
        """
        返回上一个页面
        @return:
        """
        self.driver.back()

    def clear(self, locator: tuple, timeout=10):
        """清空输入框"""
        element = self.find_element(locator=locator, timeout=timeout)
        element.clear()

    def message_submit(self, locator: tuple, timeout=10):
        """按钮信息"""
        element = self.find_element(locator=locator, timeout=timeout)
        if element is not False:
            return element
        else:
            return False

    def get_element_attribute(self, locator: tuple, timeout=10):
        """获取元素属性值"""
        element = self.find_element(locator=locator, timeout=timeout)
        return element.get_attribute('value')

    def is_attribute_in_username(self, locator: tuple, attribute, timeout=10):
        """
        判断已知的属性值是否和元素的属性值相同,如果相同返回True
        @param locator:
        @param timeout:
        @return:
        """
        result_attribute = self.get_element_attribute(locator=locator, timeout=timeout)
        if result_attribute is not False:
            return result_attribute == attribute
        else:
            return result_attribute


if __name__ == '__main__':
    base = Base(open_browser())
    url = 'http://www.baidu.com'
    base.open_url(url)
    locator = ('id', 'kw_')
    # base.find_element(locator)
    base.send_keys(locator=locator, text='123')
